package com.excel.qlexpress;



import com.corpgovernment.organization.Bo.SyncEmployeeInfoBo;
import com.corpgovernment.organization.entity.SyncOrganizationRequestEntity;
import com.corpgovernment.organization.enumm.ServiceErrorEnum;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.util.*;

@Slf4j
public class ImportQlUtils {


    public static Map<String,Object> checkEmploy(List<String> expressGroup, Map<String,Object> contextMap) {
        Map<String,Object> result = new HashMap<>();
        try {
            ExpressRunner runner = new ExpressRunner();

            IExpressContext<String, Object> context = new DefaultContext<>();
            for (Map.Entry<String, Object> entry : contextMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                context.put(key, value);
            }

            for (Map.Entry<String, CheckErrorConditionEnum> entry : CheckErrorConditionEnum.CheckConditionMap.entrySet()) {
                // 注册宏
                String key = entry.getKey();
                CheckErrorConditionEnum value = entry.getValue();
                runner.addMacro(key, value.getExpression());
            }

            for (Map.Entry<String, CheckErrorFunctionEnum> entry : CheckErrorFunctionEnum.CheckConditionMap.entrySet()) {
                // 注册函数
                CheckErrorFunctionEnum item = entry.getValue();
                runner.addFunctionOfClassMethod(item.getFunctionName(), item.getClassName(), item.getFunctionName(), item.getParameterClassTypes(),item.getFunctionName()+"方法执行失败");
            }

            for (String i : expressGroup) {

                try {
                    // 根据group分组来获取所有的校验条件并输出 -- 宏
                    List<CheckErrorConditionEnum> items = CheckErrorConditionEnum.getExpressByGroup(i);
                    for (int j = 0; j < items.size(); j++) {
                        CheckErrorConditionEnum item = items.get(j);
                        if (item == null) {
                            continue;
                        }
                        Boolean itemResult = (Boolean) runner.execute(item.getExpression(), context, null, true, false);
                        if (itemResult) {
                            result.put(i, item);
                        }
                    }

                    log.info("checkEmploy CheckErrorConditionEnum {}",result);
                    // 根据group分组来获取所有的校验条件并输出 -- 函数方法
                    List<CheckErrorFunctionEnum> functionEnums = CheckErrorFunctionEnum.getExpressByGroup(i);

                    for (int j = 0; j < functionEnums.size(); j++) {
                        CheckErrorFunctionEnum item = functionEnums.get(j);
                        if (item == null) {
                            continue;
                        }
                        Object itemResult = runner.execute(item.getExpression(), context, null, true, true);
                        if (itemResult instanceof Boolean) {
                            if((Boolean)itemResult)
                            result.put(i, item);
                        }else {
                            result.put(i, itemResult);
                        }
                    }

                    log.info("checkEmploy CheckErrorFunctionEnum {}",result);

                }catch (Exception e) {
                    // 处理表达式执行过程中的异常
                    log.error("express {} execute is error ",i);
                    result.put(i, false);
                }
            }
        } catch (Exception e) {
            // 处理表达式执行过程中的异常
            log.error("apply express execute is error ",e);
        }
        return result;
    }

    public static Map<String, Object> buildEmployCheckContextMap(SyncEmployeeInfoBo syncEmployeeInfoBo) {

        Map<String, Object> contextMap = new HashMap<>();
        Optional.ofNullable(syncEmployeeInfoBo).ifPresent(s -> contextMap.put(CheckContextEnum.EMPLOY.getKey(), s));

        return contextMap;
    }

    public static Map<String, Object> buildOrgCheckContextMap(SyncOrganizationRequestEntity.SyncOrganizationInfoEntity orgInfo) {

        Map<String, Object> contextMap = new HashMap<>();
        Optional.ofNullable(orgInfo).ifPresent(s -> contextMap.put(CheckContextEnum.ORG.getKey(), s));
        Optional.ofNullable(orgInfo).ifPresent(s -> contextMap.put(CheckContextEnum.ORG_BASIC.getKey(), s.getBasicInfo()));
        Optional.ofNullable(orgInfo).ifPresent(s -> contextMap.put(CheckContextEnum.ORG_CONTACT.getKey(), s.getContactInfo()));
        Optional.ofNullable(orgInfo).ifPresent(s -> contextMap.put(CheckContextEnum.ORG_INVOICE_LIST.getKey(), s.getInvoiceList()));
        return contextMap;
    }

    public static Map<String, String> getCheckFailMsg(Map<String, Object> stringObjectMap) {
        Map<String, String> res = new HashMap<>();
        for (Map.Entry<String, Object> entry : stringObjectMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if(value instanceof CheckErrorConditionEnum){
                res.put(key, ((CheckErrorConditionEnum) value).getValidTip());
                continue;
            }
            if(value instanceof CheckErrorFunctionEnum){
                res.put(key, ((CheckErrorFunctionEnum) value).getValidTip());
                continue;
            }
            if(value instanceof ServiceErrorEnum){
                if(ServiceErrorEnum.Success != (ServiceErrorEnum)value){
                    res.put(key, ((ServiceErrorEnum) value).getErrorMessage());
                    continue;
                }else {
                    continue;
                }
            }

            res.put(key, "未知错误");
        }
        return res;
    }


    public static void main(String[] args) {

        List<SyncEmployeeInfoBo> list = new ArrayList<>();
        SyncEmployeeInfoBo syncEmployeeInfoBo = new SyncEmployeeInfoBo();
        syncEmployeeInfoBo.setUid("111111111111111111111");
        syncEmployeeInfoBo.setPostCode("");
        syncEmployeeInfoBo.setNationality("");
        syncEmployeeInfoBo.setGender("M");
        syncEmployeeInfoBo.setCountryCode("+86666666666");
        syncEmployeeInfoBo.setMobilePhone("123456789012");
        syncEmployeeInfoBo.setCardInfoList(new ArrayList<>());
        //syncEmployeeInfoBo.setEmail("aa");
        syncEmployeeInfoBo.setBirthday("2024-02-24");
        syncEmployeeInfoBo.setJobCode("222222222222222222222222222222222222222222222222222222");

        list.add(syncEmployeeInfoBo);

        SyncEmployeeInfoBo syncEmployeeInfoBo1 = new SyncEmployeeInfoBo();
        BeanUtils.copyProperties(syncEmployeeInfoBo,syncEmployeeInfoBo1);

        list.add(syncEmployeeInfoBo1);

        Map<String, String> res = getCheckFailMsg( checkEmploy(new ArrayList<>(Arrays.asList("员工编号","员工职级编号","员工国籍","员工性别",
                        "手机国家码","手机号码","员工名字","员工证件","员工邮箱","员工生日","员工岗位","员工类型")),
                buildEmployCheckContextMap(syncEmployeeInfoBo)));
        System.out.println(1);


        String orgJson = "{ " +
                " \"lineNo\": \"3\", " +
                " \"recordId\": null, " +
                " \"isDelete\": false, " +
                " \"basicInfo\": { " +
                "  \"mainLineNo\": \"3\", " +
                "  \"lineNo\": \"3\", " +
                "  \"orgId\": null, " +
                "  \"name\": \"hc_123\", " +
                "  \"type\": \"D\", " +
                "  \"parentOrgId\": null, " +
                "  \"topOrgId\": null, " +
                "  \"isActive\": true, " +
                "  \"businessCode\": \"hc_123444444444444444444444444444444444444444444444444444444444\", " +
                "  \"parentBusinessCode\": \"hc666\", " +
                "  \"costCenterInfo\": null, " +
                "  \"costCenterInfoDefault\": \"hc666\" " +
                " }, " +
                " \"contactInfo\": null, " +
                " \"invoiceList\": [{ " +
                "  \"mainLineNo\": \"3\", " +
                "  \"lineNo\": \"2\", " +
                "  \"invoiceTitle\": \"1111\", " +
                "  \"taxId\": \"11111\", " +
                "  \"accountBank\": \"11111\", " +
                "  \"accountCardNo\": \"1111\", " +
                "  \"corporationPhone\": \"11111\", " +
                "  \"corporationAddress\": \"1111\" " +
                " }], " +
                " \"deliveryAddressList\": [{ " +
                "  \"mainLineNo\": \"3\", " +
                "  \"lineNo\": \"2\", " +
                "  \"provinceName\": \"安徽\", " +
                "  \"cityName\": \"安庆\", " +
                "  \"districtName\": \"潜山\", " +
                "  \"address\": \"111\", " +
                "  \"postCode\": \"246300\", " +
                "  \"recipientName\": \"222\", " +
                "  \"recipientCountryCode\": \"+86\", " +
                "  \"recipientPhone\": \"18075374783\", " +
                "  \"isDefault\": false " +
                " }], " +
                " \"orgConfigEntityList\": [{ " +
                "  \"mainLineNo\": \"3\", " +
                "  \"lineNo\": \"2\", " +
                "  \"businessCode\": \"hc_123\", " +
                "  \"costCenterIsNeed\": \"是\", " +
                "  \"projectIsNeed\": \"否\", " +
                "  \"type\": null " +
                " }], " +
                " \"payTypeConfigList\": [{ " +
                "  \"mainLineNo\": \"3\", " +
                "  \"lineNo\": \"2\", " +
                "  \"businessCode\": \"hc_123\", " +
                "  \"orgId\": null, " +
                "  \"flight\": \"统一支付\", " +
                "  \"train\": \"统一支付\", " +
                "  \"hotel\": \"统一支付\", " +
                "  \"car\": \"统一支付\", " +
                "  \"flightintl\": \"统一支付\", " +
                "  \"hotelintl\": \"统一支付\" " +
                " }], " +
                " \"postInfoList\": null " +
                "}";
        SyncOrganizationRequestEntity.SyncOrganizationInfoEntity orgInfo = JsonUtils.parse(orgJson,SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.class);

        Map<String, String> orgFailMsg = getCheckFailMsg( checkEmploy(new ArrayList<>(Arrays.asList("组织信息","组织性质","组织-成本中心")),
                buildOrgCheckContextMap(orgInfo)));

        System.out.println(orgFailMsg);


    }

}
